package com.wongoing.api.wechat.action;

import java.io.ByteArrayOutputStream;
import java.util.Map;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.wongoing.api.XmlHelper;
import com.wongoing.api.wechat.pub.WebChat;
import com.wongoing.api.wechat.pub.entity.JsapiTicket;
import com.wongoing.api.wechat.pub.entity.Message;
import com.wongoing.api.wechat.pub.entity.PageAccessToken;
import com.wongoing.api.wechat.pub.entity.UserInfo;
import com.wongoing.api.wechat.pub.service.WebChatService;
import com.wongoing.bus.util.Constants;
import com.wongoing.jwt.JwtUserModel;
import com.wongoing.jwt.TokenManager;
import com.wongoing.sys.viewmodel.JsonResult;
import com.wongoing.util.LogService;
import com.wongoing.util.ModelAndViewConstants;
import com.wongoing.util.Status;

/**
 * 功能说明：微信公众号接入及菜单链接处理
 * 修改说明：
 * @author zhenglibing
 * @date 2018年1月11日 上午10:19:30
 * @version 0.1
 */
@Controller
@RequestMapping("webchat/pub")
public class PubAction {
	@Autowired
	private WebChatService webChatService;
//	@Autowired
//	private SysCustomerService sysCustomerService;

	/**
	 * 功能说明：微信公众号接入处理方法
	 * 修改说明：
	 * @author zhenglibing
	 * @date 2018年1月11日 上午10:19:02
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @param echostr
	 * @param request
	 * @param response
	 */
	@RequestMapping("/index")
	public void index(String signature, String timestamp, String nonce, String echostr, HttpServletRequest request, HttpServletResponse response) {
		//如果微信接入参数为null则不做任何处理，直接终止
		if (null == signature || null == timestamp || null == nonce || "".equals(signature) || "".equals(timestamp) || "".equals(nonce)) {
			LogService.getInstance(this).warn("非微信接入，不做任何处理...");
			return;
		}
		
		try {
			//获取客户端请求的方式（GET为验证，POST为接收消息处理）
			String method = request.getMethod().toLowerCase();
			if (method.equals("get")) {
				//微信接入验证
				LogService.getInstance(this).debug("微信接入验证参数如下：");
				LogService.getInstance(this).debug("signature=" + signature);
				LogService.getInstance(this).debug("timestamp=" + timestamp);
				LogService.getInstance(this).debug("nonce=" + nonce);
				LogService.getInstance(this).debug("echostr=" + echostr);
				
				boolean ret = WebChat.checkSignature(Constants.WEBCHAT_PUB_TOKEN, Constants.WEBCHAT_PUB_ENCODINGAESKEY, Constants.WEBCHAT_PUB_APPID, signature, timestamp, nonce);
				if (ret) {
					LogService.getInstance(this).debug("微信接入签名验证成功!");
					response.getWriter().write(echostr);
				}
				else {
					LogService.getInstance(this).error("微信接入签名验证失败!");
				}
			}
			else if (method.equals("post")) {
				//接收微信消息
				ServletInputStream s = request.getInputStream();
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
		        byte buff[] = new byte[ 1024 ];
		        int read;
		        while( ( read = s.read( buff ) ) > 0 ) {
		            baos.write( buff, 0, read );
		        }
				byte[] b = baos.toByteArray();				
				String postxmlstr = new String(b, "utf-8");
				baos.close();
				if (null != postxmlstr && !"".equals(postxmlstr)) {
					LogService.getInstance(this).debug("接收微信消息，postxmlstr=" + postxmlstr);
					Message msg = XmlHelper.xmlToEntity(postxmlstr, Message.class);
					this.publicReciveMessage(msg);
				}
				else {
					LogService.getInstance(this).warn("接收微信消息，postxmlstr为null!");
				}
			}
			
			LogService.getInstance(this).debug("微信接入成功!");
			response.getWriter().close();
		}
		catch(Exception ex) {
			LogService.getInstance(this).error("微信接入异常：" + ex.getMessage(), ex);
		}
		
		return;
	}
	
	/**
	 * 功能说明：微信公众号接收消息业务方法
	 * 修改说明：
	 * @author zhenglibing
	 * @date 2018年1月12日 上午11:24:33
	 * @param msg
	 */
	private void publicReciveMessage(Message msg) {
		if (null != msg) {
			if (msg.getMsgType().toLowerCase().equals("event")) {
				//事件处理
				if (msg.getEvent().toLowerCase().equals("subscribe")) {
					//关注公众号
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=subscribe");
				}
				else if (msg.getEvent().toLowerCase().equals("unsubscribe")) {
					//取消关注
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=unsubscribe");
				}
				else if (msg.getEvent().toLowerCase().equals("location")) {
					//上报地理位置
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=location");
				}
				else if (msg.getEvent().toLowerCase().equals("click")) {
					//上报菜单
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=click");
				}
				else if (msg.getEvent().toLowerCase().equals("view")) {
					//点击菜单跳转链接
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=view");
				}
				else if (msg.getEvent().toLowerCase().equals("scancode_push")) {
					//扫码推
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=scancode_push");
				}
				else if (msg.getEvent().toLowerCase().equals("scancode_waitmsg")) {
					//扫码推且弹出“消息接收中”
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=scancode_waitmsg");
				}
				else if (msg.getEvent().toLowerCase().equals("pic_sysphoto")) {
					//弹出系统拍照发图
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=pic_sysphoto");
				}
				else if (msg.getEvent().toLowerCase().equals("pic_photo_or_album")) {
					//弹出拍照或者相册发图
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=pic_photo_or_album");
				}
				else if (msg.getEvent().toLowerCase().equals("pic_weixin")) {
					//弹出微信相册发图器
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=pic_weixin");
				}
				else if (msg.getEvent().toLowerCase().equals("location_select")) {
					//弹出地理位置选择器
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=location_select");
				}
				else if (msg.getEvent().toLowerCase().equals("batch_job_result")) {
					//异步任务完成事件
					LogService.getInstance(this).debug("接收消息处理测试：msgType=event,event=batch_job_result");
				}
			}
			else if (msg.getMsgType().toLowerCase().equals("text")) {
				//文本消息
				LogService.getInstance(this).debug("接收消息处理测试：msgType=text");
			}
			else if (msg.getMsgType().toLowerCase().equals("image")) {
				//图片消息
				LogService.getInstance(this).debug("接收消息处理测试：msgType=image");
			}
			else if (msg.getMsgType().toLowerCase().equals("voice")) {
				//音频消息
				LogService.getInstance(this).debug("接收消息处理测试：msgType=voice");
			}
			else if (msg.getMsgType().toLowerCase().equals("video")) {
				//视屏消息
				LogService.getInstance(this).debug("接收消息处理测试：msgType=video");
			}
		}
	}
	
	/**
	 * 功能说明：微信公众号菜单链接处理
	 * 修改说明：
	 * @author zhenglibing
	 * @date 2018年1月11日 上午9:08:59
	 * @param code code作为换取access_token的票据，每次用户授权带上的code将不一样，code只能使用一次，5分钟未被使用自动过期。
	 * @param state 重定state参数，开发者可以填写a-zA-Z0-9的参数值，最多128字节，此处填写的是最终微站页面名称。
	 * @return 
	 */
	@RequestMapping(value = "/link")
	public ModelAndView link(String code, String state, HttpServletRequest request) {
		ModelAndView mv = null;
		try {
			LogService.getInstance(this).debug("code=" + code + ",state=" + state);
			if (null == code || "".equals(code)) {
				LogService.getInstance(this).warn("微信网页授权跳转异常：code为null!");
				mv = new ModelAndView(ModelAndViewConstants.ERROR_VIEW);
				return mv;
			}
			PageAccessToken pageAccessToken = WebChat.getPageAccessTokenEntity(Constants.WEBCHAT_PUB_APPID, Constants.WEBCHAT_PUB_APPSECRET, code);
			if (pageAccessToken == null) {
				LogService.getInstance(this).warn("微信网页授权跳转异常：获取pageAccessToken为null!");
				mv = new ModelAndView(ModelAndViewConstants.ERROR_VIEW);
				return mv;
			}
			if (pageAccessToken.getErrcode() != 0) {
				LogService.getInstance(this).warn("微信网页授权跳转异常：获取pageAccessToken失败，errcode=" + pageAccessToken.getErrcode() + ",errmsg=" + pageAccessToken.getErrmsg());
				mv = new ModelAndView(ModelAndViewConstants.ERROR_VIEW);
				return mv;
			}
			
			String openid = pageAccessToken.getOpenid();
			String jwtToken = "";
			
			// 判断openId 是否绑定, 
//			SysCustomer sysCustomer = sysCustomerService.getCustomerByWxOpenId(openid);
//			// 已经绑定, 生成token
//			if(sysCustomer != null && StringUtils.isNotBlank(sysCustomer.getUserName())){
//				JwtUserModel loginUser = new JwtUserModel(sysCustomer.getId(), sysCustomer.getUserName());
//				jwtToken = TokenManager.getInstance().createToken(loginUser);
//			}
			
			mv = new ModelAndView();

			// 获取 js api ticket
			String timestamp = WebChat.getTimestamp();
			String nonceStr = WebChat.getNonceStr();
			String jsApiTicket = "";
			JsapiTicket ticket = this.webChatService.getJsApiTicket();
			if (ticket == null || ticket.getErrcode() != 0) {
				if (ticket == null) {
					LogService.getInstance(this).warn("微信网页授权跳转异常：获取jsapiTicket失败,jsapiTicket is null!");
				}
				else {
					LogService.getInstance(this).warn("微信网页授权跳转异常：获取jsapiTicket失败，errcode=" + ticket.getErrcode() + ",errmsg=" + ticket.getErrmsg());
				}
				mv = new ModelAndView(ModelAndViewConstants.ERROR_VIEW);
				return mv;
			}
			else {
				jsApiTicket = ticket.getTicket();
			}
			
			// 统一跳转到index页面
			String url = "%s/index.html?state=%s&openId=%s&token=%s&appId=%s&nonceStr=%s&timestamp=%s";
			url = String.format(url, "http://mobile.zhipinji.com", state, openid, jwtToken, Constants.WEBCHAT_PUB_APPID, nonceStr, timestamp);
			
			//String signUrl = request.getScheme()+"://"+ request.getServerName() + url;
			String signUrl = url;
			String sign = WebChat.getJsSdkSign(jsApiTicket, timestamp, nonceStr, signUrl);
			
			url = url + "#/"+state+"?signature=" + sign;
			
			System.out.println("redirect url=" + url);
			mv.setViewName("redirect:" + url);
			LogService.getInstance(this).debug("微信网页授权跳转成功!url=" + url);
		}
		catch(Exception ex) {
			LogService.getInstance(this).error("微信网页授权跳转异常：" + ex.getMessage(), ex);
			mv = new ModelAndView(ModelAndViewConstants.ERROR_VIEW);
		}
		return mv;
	}
	
	
	
	/**
	 * 功能说明：根据openid获取微信用户信息
	 * 修改说明：
	 * @author zhenglibing
	 * @date 2018年1月15日 下午2:37:53
	 * @param openid
	 * @return 以json方式返回微信用户信息
	 */
	@ResponseBody
	@RequestMapping(value = "/getUserInfo")
	public Map<String, Object> getUserInfo(String openid) {
		Map<String, Object> result = null;
		try {
			if (null != openid && !"".equals(openid)) {
				UserInfo userInfo = WebChat.getUserInfo(this.webChatService.getPubAccessToken().getAccess_token(), openid);
				result = JsonResult.jsonWsReturn(Status.SUCCESS.getCode(), null, userInfo);
			}
			else {
				result = JsonResult.jsonWsReturn(Status.ERROR.getCode(), "参数openid为null!", null);
			}
		}
		catch(Exception ex) {
			LogService.getInstance(this).error("根据openid获取微信用户信息异常：" + ex.getMessage(), ex);
			result = JsonResult.jsonWsReturn(Status.ERROR.getCode(), "参数openid=" + openid, null);
			
		}
		return result;
	}
}
